package com.zdcp.web.controller.system;

import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.zdcp.core.annotation.FormToken;
import com.zdcp.core.annotation.Log;
import com.zdcp.core.bean.JsonResult;
import com.zdcp.core.bean.TableInfo;
import com.zdcp.core.enums.BusinessType;
import com.zdcp.core.enums.TokenType;
import com.zdcp.core.web.controller.BaseController;
import com.zdcp.core.web.util.ExcelUtils;
import com.zdcp.system.bean.SysRole;
import com.zdcp.system.bean.SysUser;
import com.zdcp.system.bean.SysUserRole;
import com.zdcp.system.constant.SysConstants;
import com.zdcp.system.service.ISysRoleService;
import com.zdcp.system.service.ISysUserService;
import com.zdcp.system.shiro.util.ShiroUtils;
import com.zdcp.util.text.Convert;

/**
 * 系统角色控制层
 * 
 * @author yweijian
 * @date 2019年8月18日
 * @version 1.0
 */
@Controller
@RequestMapping("/system/role")
public class SysRoleController extends BaseController {
	private String prefix = "system/role";

	@Autowired
	private ISysRoleService roleService;

	@Autowired
	private ISysUserService userService;

	@RequiresPermissions("system:role:view")
	@GetMapping()
	public String role() {
		return prefix + "/role";
	}

	@SuppressWarnings("unchecked")
	@RequiresPermissions("system:role:list")
	@PostMapping("/list")
	@ResponseBody
	public TableInfo list(SysRole role) {
		initPageQuery(role);
		roleService.selectRoleList(query);
		return getDataTable(query);
	}

	@Log(title = "角色管理", businessType = BusinessType.EXPORT)
	@RequiresPermissions("system:role:export")
	@PostMapping("/export")
	@ResponseBody
	public JsonResult export(SysRole role) {
		List<SysRole> list = roleService.selectRoleList(role);
		ExcelUtils<SysRole> util = new ExcelUtils<SysRole>(SysRole.class);
		return util.exportExcel(list, "角色数据");
	}

	/**
	 * 新增角色
	 */
	@FormToken
	@GetMapping("/add")
	public String add() {
		return prefix + "/add";
	}

	/**
	 * 新增保存角色
	 */
	@FormToken(TokenType.DESTROY)
	@RequiresPermissions("system:role:add")
	@Log(title = "角色管理", businessType = BusinessType.INSERT)
	@PostMapping("/add")
	@ResponseBody
	public JsonResult addSave(@Validated SysRole role) {
		if (SysConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) {
			return JsonResult.error("新增角色'" + role.getRoleName() + "'失败，角色名称已存在");
		} else if (SysConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) {
			return JsonResult.error("新增角色'" + role.getRoleName() + "'失败，角色权限已存在");
		}
		role.setCreateBy(ShiroUtils.getLoginName());
		ShiroUtils.clearCachedAuthorizationInfo();
		roleService.insertRole(role);
		return JsonResult.success();

	}

	/**
	 * 修改角色
	 */
	@GetMapping("/edit/{roleId}")
	public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap) {
		mmap.put("role", roleService.selectRoleById(roleId));
		return prefix + "/edit";
	}

	/**
	 * 修改保存角色
	 */
	@RequiresPermissions("system:role:edit")
	@Log(title = "角色管理", businessType = BusinessType.UPDATE)
	@PostMapping("/edit")
	@ResponseBody
	public JsonResult editSave(@Validated SysRole role) {
		if (SysConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) {
			return JsonResult.error("修改角色'" + role.getRoleName() + "'失败，角色名称已存在");
		} else if (SysConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) {
			return JsonResult.error("修改角色'" + role.getRoleName() + "'失败，角色权限已存在");
		}
		role.setUpdateBy(ShiroUtils.getLoginName());
		ShiroUtils.clearCachedAuthorizationInfo();
		roleService.updateRole(role);
		return JsonResult.success();
	}

	/**
	 * 角色分配数据权限
	 */
	@GetMapping("/authDataScope/{roleId}")
	public String authDataScope(@PathVariable("roleId") Long roleId, ModelMap mmap) {
		mmap.put("role", roleService.selectRoleById(roleId));
		return prefix + "/dataScope";
	}

	/**
	 * 保存角色分配数据权限
	 */
	@RequiresPermissions("system:role:edit")
	@Log(title = "角色管理", businessType = BusinessType.UPDATE)
	@PostMapping("/authDataScope")
	@ResponseBody
	public JsonResult authDataScopeSave(SysRole role) {
		role.setUpdateBy(ShiroUtils.getLoginName());
		if (roleService.authDataScope(role) > 0) {
			ShiroUtils.setSysUser(userService.selectUserById(ShiroUtils.getSysUser().getUserId()));
			return JsonResult.success();
		}
		return JsonResult.error();
	}

	@RequiresPermissions("system:role:remove")
	@Log(title = "角色管理", businessType = BusinessType.DELETE)
	@PostMapping("/remove")
	@ResponseBody
	public JsonResult remove(String ids) {
		try {
			roleService.deleteRoleByIds(Convert.toStrArray(ids));
			return JsonResult.success();
		} catch (Exception e) {
			return JsonResult.error(e.getMessage());
		}
	}

	/**
	 * 校验角色名称
	 */
	@PostMapping("/checkRoleNameUnique")
	@ResponseBody
	public String checkRoleNameUnique(SysRole role) {
		return roleService.checkRoleNameUnique(role);
	}

	/**
	 * 校验角色权限
	 */
	@PostMapping("/checkRoleKeyUnique")
	@ResponseBody
	public String checkRoleKeyUnique(SysRole role) {
		return roleService.checkRoleKeyUnique(role);
	}

	/**
	 * 选择菜单树
	 */
	@GetMapping("/selectMenuTree")
	public String selectMenuTree() {
		return prefix + "/tree";
	}

	/**
	 * 角色状态修改
	 */
	@Log(title = "角色管理", businessType = BusinessType.UPDATE)
	@RequiresPermissions("system:role:edit")
	@PostMapping("/changeStatus")
	@ResponseBody
	public JsonResult changeStatus(SysRole role) {
		roleService.changeStatus(role);
		return JsonResult.success();
	}

	/**
	 * 分配用户
	 */
	@RequiresPermissions("system:role:edit")
	@GetMapping("/authUser/{roleId}")
	public String authUser(@PathVariable("roleId") Long roleId, ModelMap mmap) {
		mmap.put("role", roleService.selectRoleById(roleId));
		return prefix + "/authUser";
	}

	/**
	 * 查询已分配用户角色列表
	 */
	@SuppressWarnings("unchecked")
	@RequiresPermissions("system:role:list")
	@PostMapping("/authUser/allocatedList")
	@ResponseBody
	public TableInfo allocatedList(SysUser user) {
		initPageQuery(user);
		userService.selectAllocatedList(query);
		return getDataTable(query);
	}

	/**
	 * 取消授权
	 */
	@Log(title = "角色管理", businessType = BusinessType.GRANT)
	@PostMapping("/authUser/cancel")
	@ResponseBody
	public JsonResult cancelAuthUser(SysUserRole userRole) {
		roleService.deleteAuthUser(userRole);
		return JsonResult.success();
	}

	/**
	 * 批量取消授权
	 */
	@Log(title = "角色管理", businessType = BusinessType.GRANT)
	@PostMapping("/authUser/cancelAll")
	@ResponseBody
	public JsonResult cancelAuthUserAll(Long roleId, String userIds) {
		roleService.deleteAuthUsers(roleId, userIds);
		return JsonResult.success();
	}

	/**
	 * 选择用户
	 */
	@GetMapping("/authUser/selectUser/{roleId}")
	public String selectUser(@PathVariable("roleId") Long roleId, ModelMap mmap) {
		mmap.put("role", roleService.selectRoleById(roleId));
		return prefix + "/selectUser";
	}

	/**
	 * 查询未分配用户角色列表
	 */
	@SuppressWarnings("unchecked")
	@RequiresPermissions("system:role:list")
	@PostMapping("/authUser/unallocatedList")
	@ResponseBody
	public TableInfo unallocatedList(SysUser user) {
		initPageQuery(user);
		userService.selectUnallocatedList(query);
		return getDataTable(query);
	}

	/**
	 * 批量新增选择用户授权
	 */
	@Log(title = "角色管理", businessType = BusinessType.GRANT)
	@PostMapping("/authUser/grantAll")
	@ResponseBody
	public JsonResult grantAuthUserAll(Long roleId, String userIds) {
		roleService.insertAuthUsers(roleId, userIds);
		return JsonResult.success();
	}
}